package br.usp.ime.ingpos.web.controllers;

import br.com.caelum.vraptor.Get;
import br.com.caelum.vraptor.Path;
import br.com.caelum.vraptor.Post;
import br.com.caelum.vraptor.Resource;
import br.com.caelum.vraptor.Result;
import br.com.caelum.vraptor.Validator;
import br.com.caelum.vraptor.validator.Validations;
import br.usp.ime.ingpos.modelo.Usuario;
import br.usp.ime.ingpos.services.SenhaService;
import br.usp.ime.ingpos.services.UsuarioService;
import br.usp.ime.ingpos.web.interceptors.IrrestrictAccess;
import br.usp.ime.ingpos.web.interceptors.Transactional;

/**
 * Controlador de requisicoes. Responsavel por executar logica de
 * redirecionamento, incluindo desvios para paginas e definicoes de mensagens de
 * erro.
 */
@Resource
@IrrestrictAccess
public class LoginController
{
    private final Result result;
    private final UsuarioService usuarioService;
    private final Validator validador;
    private final SenhaService senhaService;

    private Usuario usuarioPagina;

    public LoginController(
        final Result result,
        final Validator validador,
        final UsuarioService usuarioService,
        final SenhaService senhaService )

    {
        this.result = result;
        this.validador = validador;
        this.usuarioService = usuarioService;
        this.senhaService = senhaService;
    }

    @Get
    @Path( "/login" )
    public void login()
    {
        if( usuarioService.isUsuarioAutenticado() ) {
            // Caso usuario ja esteja logado, o mesmo nao acessa a tela de login
            // novamente, e direcionado diretamente para home
            result.redirectTo( IndexController.class ).index();
        } else if( usuarioPagina != null ) {
            usuarioPagina.setSenha( "" );
            result.include( "usuario", usuarioPagina );
        }
    }

    @Post
    @Path( "/login" )
    @Transactional
    public void login(
        Usuario usuario )
    {
        usuarioPagina = usuario;

        final boolean success = usuarioService.autenticar( usuario.getEmail(), usuario.getSenha() );

        if( success ) {
            result.redirectTo( IndexController.class ).index();
        } else {
            validador.checking( new Validations() {
                {
                    that( false, "erro_tipo_login", "erro_msg_login_invalido" );
                }
            } );
            validador.onErrorRedirectTo( getClass() ).login();
        }
    }

    @Get
    @Path( "/logout" )
    public void logout()
    {
        usuarioService.deautenticate();

        result.redirectTo( getClass() ).login();
    }

    @Get
    @Path( "/login/forgot" )
    public void forgot()
    {
    }

    @Post
    @Path( "/login/forgot" )
    public void forgot(
        String email )
    {
        if( senhaService.enviarEmailSucedido( email ) ) {
            result.include( "messages", "email_sent" );
            result.redirectTo( getClass() ).forgot();
        } else {
            validador.checking( new Validations() {
                {
                    that( false, "erro_tipo_email_sem_lei", "email_doesnt_exist_user" );
                }
            } );
            validador.onErrorForwardTo( getClass() ).forgot();
        }
    }

    @Get
    @Path( "/login/resetarSenha/{hashUsuario}" )
    public void resetarSenha(
        final String hashUsuario )
    {
        final Usuario usuario = usuarioService.procurarPorHash( hashUsuario );

        String email = "";
        if( usuario != null )
            email = usuario.getEmail();

        result.include( "email", email );
        result.include( "hash", hashUsuario );
    }

    @Post
    @Path( "/login/resetarSenha" )
    @Transactional
    public void resetarSenha(
        String email,
        String hash,
        final String novaSenha,
        String confirmaNovaSenha )
    {
        Usuario usuario = usuarioService.procurarPorEmail( email );
        Usuario usuarioPorHash = usuarioService.procurarPorHash( hash );
        if(usuario != usuarioPorHash) return;

        if( novaSenha.compareTo( confirmaNovaSenha ) == 0 ) {
            ;
        } else {
            validador.checking( new Validations() {
                {
                    that( false, "erro_tipo_email", "erro_senha_sugerida_nao_confere" );
                }
            } );
            validador.onErrorForwardTo( getClass() ).resetarSenha( usuario.getHash() );
        }
        
        validador.checking( new Validations() {
            {
                that( !novaSenha.isEmpty(), "erro_tipo_senha", "erro_senha_vazio" );
            }
        } );
        
        validador.onErrorForwardTo( getClass() ).resetarSenha( usuario.getHash() );

        if( senhaService.atualizarSenha( email, novaSenha ) ) {
            result.include( "messages", "senha_alterado_sucesso" );
            result.redirectTo( getClass() ).resetarSenha( usuario.getHash() );
        } else {
            validador.checking( new Validations() {
                {
                    that( false, "erro_tipo_email", "email_doesnt_exist_user" );
                }
            } );
            validador.onErrorForwardTo( getClass() ).forgot();
        }
    }
}